﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Messaging;
using MG.Repository;
using MG.SmartHMI.Common;
using MG.SmartHMI.Domain;
using MG.SmartHMI.Entity.DAO;
using MG.SmartHMI.Model;
using MG.SmartHMI.Model.Common;
using SqlSugar;

namespace MG.SmartHMI.ViewModel
{
    public partial class DebugViewModel : ObservableRecipient
    {
        #region Parm

        [ObservableProperty]
        private List<ButtonViewModel> listButton = new();

        [ObservableProperty]
        private List<BaseItemsControl> listCheckBox = new();

        [ObservableProperty]
        private List<BaseItemsControl> listSwitch = new();

        [ObservableProperty]
        private List<BaseItemsControl> listInputSignal = new();

        [ObservableProperty]
        private List<BaseItemsControl> listDispBox = new();

        [ObservableProperty]
        private List<AxisBoxViewModel> listAxis = new();

        [ObservableProperty]
        private bool visiblityButton;

        [ObservableProperty]
        private bool visiblityCheckBox;

        [ObservableProperty]
        private bool visiblitySwitch;

        [ObservableProperty]
        private bool visiblityInputSignal;

        [ObservableProperty]
        private bool visiblityDispBox;

        [ObservableProperty]
        private bool visiblityAxis;

        #endregion Parm

        #region construct

        public DebugViewModel()
        {
            Register();
        }

        #endregion construct

        #region Init Event

        private void InitUI()
        {
            ListCheckBox.ForEach(t => t.UpdateRead());
            ListSwitch.ForEach(t => t.UpdateRead());
            ListInputSignal.ForEach(t => t.UpdateRead());
            ListDispBox.ForEach(t => t.UpdateRead());
        }

        private void Update2UI()
        {
            var listregister = RepositoryService<RegisterConfig>.Instance.Query(t => t.Disp_DebugView && !t.IsDelete).OrderBy(t2 => t2.SortLevel).ToList();
            List<ButtonViewModel> primbuttons = new();
            List<ButtonViewModel> normbuttons = new();
            List<BaseItemsControl> checks = new();
            List<BaseItemsControl> switchs = new();
            List<BaseItemsControl> inputsignales = new();
            List<BaseItemsControl> dispboxes = new();
            List<AxisBoxViewModel> axis = new();

            foreach (var item in listregister)
            {
                switch (item.ControlType)
                {
                    case EnumControlType.Switch:
                        switchs.Add(new SwitchViewModel(item));
                        break;

                    case EnumControlType.InputSignal:
                        inputsignales.Add(new InputSignalViewModel(item));
                        break;

                    case EnumControlType.CheckBox:
                        checks.Add(new CheckBoxViewModel(item));
                        break;

                    case EnumControlType.DispDataBox:
                        dispboxes.Add(new DispBoxViewModel(item));
                        break;

                    case EnumControlType.NormButton:
                        normbuttons.Add(new ButtonNormViewModel(item));
                        break;

                    case EnumControlType.StartButton:
                        primbuttons.Add(new ButtonStartViewModel(item));
                        break;

                    case EnumControlType.EmgButton:
                        primbuttons.Add(new ButtonEmgViewModel(item));
                        break;

                    case EnumControlType.StopButton:
                        primbuttons.Add(new ButtonStopViewModel(item));
                        break;

                    case EnumControlType.PauseButton:
                        primbuttons.Add(new ButtonPauseViewModel(item));
                        break;

                    case EnumControlType.ResetButton:
                        primbuttons.Add(new ButtonResetViewModel(item));
                        break;

                    case EnumControlType.InputBox:
                    default:
                        break;
                }
            }

            RepositoryService<AxisConfig>.Instance.Query(t => !t.IsDelete).ToList().ForEach(x =>
            {
                axis.Add(new AxisBoxViewModel(x));
            });

            ListAxis = axis;

            primbuttons.AddRange(normbuttons);
            ListButton = primbuttons;
            ListCheckBox = checks;
            ListSwitch = switchs;
            ListInputSignal = inputsignales;
            ListDispBox = dispboxes;

            VisiblityButton = ListButton.Count() > 0;
            VisiblityCheckBox = ListCheckBox.Count() > 0;
            VisiblitySwitch = ListSwitch.Count() > 0;
            VisiblityInputSignal = ListInputSignal.Count() > 0;
            VisiblityDispBox = ListDispBox.Count() > 0;
            VisiblityAxis = ListAxis.Count() > 0;
        }

        #endregion Init Event

        #region SLOT

        private void Register()
        {
            WeakReferenceMessenger.Default.Register<string, string>(this, "DebugLoadSignal", DebugLoadSlot);
            WeakReferenceMessenger.Default.Register<string, string>(this, "DebugUnLoadSignal", DebugUnLoadSlot);
        }

        private void CircleTimeActionSlot()
        {
            Task.Run(() =>
            {
                ListInputSignal.ForEach(T => T.UpdateRead());
                ListDispBox.ForEach(T => T.UpdateRead());

                var batchres = ModbusCtrl.Instance.BatchRead();
                var boolres = ModbusCtrl.Instance.BatchReadBool();
                if (batchres.IsSuccess && boolres.IsSuccess)
                {
                    var datares = batchres.Content;
                    var databoolres = boolres.Content;
                    ListDispBox.ForEach(t => t.ParsebyBatchData(ref datares, ref databoolres));
                    ListInputSignal.ForEach(t => t.ParsebyBatchData(ref datares, ref databoolres));
                }
                ListAxis.ForEach(t => t.UpdateRead());
            });
        }

        private void DebugLoadSlot(object recipient, string message)
        {
            Task.Run(() =>
            {
                EventBus.Default.BindCircleTimeAction(CircleTimeActionSlot);
                Update2UI();
                InitUI();
            });
        }

        private void DebugUnLoadSlot(object recipient, string message)
        {
            EventBus.Default.UnBindCircleTimeAction(CircleTimeActionSlot);
        }

        #endregion SLOT
    }
}